package com.cloud.sso.web.oauth;

import com.cloud.sso.entity.Application;
import com.cloud.sso.entity.SysMenu;
import com.cloud.sso.entity.SysRole;
import com.cloud.sso.common.exception.AppException;
import com.cloud.sso.entity.SysRoleMenu;
import com.cloud.sso.oauth.obj.AppMenu;
import com.cloud.sso.oauth.obj.AppRole;
import com.cloud.sso.oauth.obj.AppUserDetails;
import com.cloud.sso.oauth.redis.AppRedisTokenStore;
import com.cloud.sso.service.ApplicationService;
import com.cloud.sso.service.MenuService;
import com.cloud.sso.service.RoleService;
import com.cloud.sso.vo.MenuVo;
import com.cloud.sso.vo.RoleVo;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.oauth2.provider.OAuth2Authentication;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import java.util.*;

@RestController
public class UserInfoController {

    @Autowired
    private AppRedisTokenStore appRedisTokenStore;

    @Autowired
    private ApplicationService applicationService;

    @Autowired
    private RoleService roleService;

    @Autowired
    private MenuService menuService;

    @RequestMapping("/user")
    public AppUserDetails user(HttpServletRequest request) {
        String beanAccessToken = request.getHeader("authorization");
        String accessToken = beanAccessToken.split(" ")[1];

        if (accessToken == null) {
            return null;
        }
        OAuth2Authentication auth2Authentication = appRedisTokenStore.readAuthentication(accessToken);

        // 查询用户应用下的角色
        String clientId = auth2Authentication.getOAuth2Request().getClientId();
        AppUserDetails appUserDetails = (AppUserDetails) auth2Authentication.getPrincipal();

        Application applicaiton = applicationService.queryByClientId(clientId);

        if (applicaiton == null) {
            throw new AppException("查询应用" + clientId + "失败");
        }

        String userId = appUserDetails.getId();

        List<RoleVo> roleList = roleService.query(userId, applicaiton.getId());

        List<AppRole> appRoles = new ArrayList<>();

        for (RoleVo sysRole : roleList) {
            AppRole appRole = new AppRole();
            BeanUtils.copyProperties(sysRole, appRole);
            appRole.setRoleId(sysRole.getId());

            // 查询角色下的菜单
            List<SysRoleMenu> roleMenus = menuService.queryRoleMenu(sysRole.getId());
            appRole.setMenuList(entityToAppMenu(roleMenus));


            appRoles.add(appRole);


        }

        appUserDetails.setRoleList(appRoles);


        // 密码置空处理
        appUserDetails.setPassword(null);

        return appUserDetails;
    }


    public Collection<GrantedAuthority> convertRoleToGrantedAuthority(Set<String> userRoleCodes) {
        if (userRoleCodes == null) {
            return new HashSet<GrantedAuthority>();
        } else {
            Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
            userRoleCodes.stream().filter((role) -> {
                return !StringUtils.isEmpty(role);
            }).forEach((role) -> {
                role = role.trim();
                if (!role.startsWith("ROLE_")) {
                    role = "ROLE_" + role;
                }

                grantedAuthorities.add(new SimpleGrantedAuthority(role));
            });
            return grantedAuthorities;
        }
    }
   /* public String parseHeaderAccessToken(HttpServletRequest httpServletRequest) {
        String authorization = httpServletRequest.getHeader("authorization");
       *//* if (authorization == null) {
            authorization = httpServletRequest.getHeader(HttpHeaders.AUTHORIZATION.toLowerCase());
        }*//*

        if (authorization == null || authorization.equals("")) {
            return null;
        }

        BearerAccessToken bearerAccessToken = null;
        try {
            bearerAccessToken = BearerAccessToken.parse(authorization);
        } catch (ParseException e) {
            e.printStackTrace();
        }

        if (bearerAccessToken == null || bearerAccessToken.equals("")) {
            return null;
        }
        return bearerAccessToken.getValue();
    }*/

    public List<AppMenu> entityToAppMenu(List<SysRoleMenu> list) {
        List<AppMenu> appMenus = new ArrayList<>();

        list.forEach(e -> {
            MenuVo sysMenu = menuService.get(e.getMenuId());

            AppMenu appMenu = new AppMenu();

            appMenu.setMenuCode(sysMenu.getMenuCode());
            appMenu.setMenuId(sysMenu.getId());
            appMenu.setMenuName(sysMenu.getMenuName());
            appMenu.setPath(sysMenu.getPath());
            appMenu.setUri(sysMenu.getUri());

            appMenus.add(appMenu);

        });

        return appMenus;
    }
}
